home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / install / package-.1 / package- / package-0.1 / bin / pkg < prev   
Text File  |  1993-04-01  |  14KB  |  673 lines

  1. #!/bin/sh
  2. #
  3. # $Id: pkg,v 1.2 1993/02/19 13:00:48 mike Exp $
  4.  
  5. # Save the name of the script for later. That way I don't have to hardcode
  6. # the name all over before I've decided what it will finally be :-)
  7. progname=`basename $0`
  8.  
  9. # If the default target directory isn't set it defaults to the current
  10. # directory.
  11. DEF_TARGET=.
  12.  
  13. # The default path to search is somewhat arbitrary...
  14. PKGPATH=.:/packages:/usr/packages:/usr/local/packages:/var/packages
  15.  
  16. # A list of possible file system types (used when trying to mount disks).
  17. FSTYPES="msdos ext2 xiafs minix ext"
  18.  
  19.  
  20. # If a defaults file exists parse it into shell syntax and source it. We
  21. # don't keep defaults files in shell syntax to avoid tempting people to
  22. # source them directly. This could be funny...
  23. if [ -r /etc/default/package ]; then
  24.     awk '
  25. /^#/        { next; }
  26. /^[ \t]*$/    { next; }
  27.         { printf "%s=%s ; export %s\n", $1, $2, $1 }
  28.     ' /etc/default/package > /tmp/pkg$$ && . /tmp/pkg$$
  29.     rm -f /tmp/pkg$$
  30. fi
  31.  
  32. target="$DEF_TARGET"
  33. if [ "$target" = "/" ]; then
  34.     target=
  35. fi
  36.  
  37. # Compression commands. You may be using compress, freeze, gzip...
  38. # These commands should work in pipelines...
  39. #COMP=compress
  40. COMP=gzip
  41. #UNCOMP=uncompress
  42. UNCOMP=gunzip
  43. ZCAT=zcat
  44.  
  45.  
  46. # If this is a traditional old Bourne shell we can probably use backslash
  47. # escapes regardless. If this is Bash we may need the -e option to the
  48. # built in echo. This seems to make Bash incompatible? Is this POSIX
  49. # behaviour? Is it a compile time configuration option in Bash? I dunno...
  50. if [ -n "$BASH_VERSION" ]; then
  51.     use_escapes="-e"
  52. else
  53.     use_escapes=""
  54. fi
  55.  
  56.  
  57. function usage()
  58. {
  59.     cat << !!MIKE_WANTS_CHOCCY!!
  60. Options:
  61.     -n
  62.         Does not actually make changes to the target directory
  63.         during a rebuild.
  64.  
  65.     -a|--add <package>
  66.         Adds the package in the specified directory to the list
  67.         of packages which are installed in the current target
  68.         directory.
  69.  
  70.     --doc|--readme <package>
  71.         Browse the documentation for the given package.
  72.  
  73.     -i|--info <regular expression>
  74.         Give information about any files installed in the current
  75.         target directory which match the given regular expression.
  76.  
  77.     --install <archive> | <device>
  78.         Extract from the given archive and add the packages found
  79.         to the current target directory. If the given name is a
  80.         device then it is mounted and all archives found on it are
  81.         extracted into the current directory.
  82.  
  83.     -l|--list
  84.         List the packages intalled in the current target directory.
  85.  
  86.     -r|--rebuild
  87.         Rebuild the current target directory by merging the map
  88.         files of the installed packages and applying the resulting
  89.         map instructions.
  90.  
  91.     -r|--remove <package>
  92.         Remove the package in the specified directory from the
  93.         list of packages which are installed in the current target
  94.         directory.
  95.  
  96.     -t|--target <directory>
  97.         Sets the current directory for installation.
  98. !!MIKE_WANTS_CHOCCY!!
  99. }
  100.  
  101.  
  102. function read_docs()
  103. {
  104.     HERE=`pwd`
  105.     TOPDIR=$1/doc
  106.  
  107.     if [ ! -d $1/doc ]; then
  108.         echo "No documentation found in $1"
  109.         return
  110.     fi
  111.  
  112.     cd $1/doc
  113.  
  114.     echo
  115.     echo "Available documents:"
  116.     echo
  117.     ls -C
  118.     echo
  119.  
  120.     doc=
  121.     while [ "$doc" != "quit" ]
  122.     do
  123.         echo -n "Enter document name (type quit when done): "
  124.         read doc
  125.         if [ -z "$doc" ]; then
  126.             echo
  127.             echo "Available documents:"
  128.             echo
  129.             ls -C
  130.             echo
  131.         elif [ -d "$doc" ]; then
  132.             case "$doc" in
  133.                 ..*|./..*)
  134.                     if [ "`pwd`" = $TOPDIR ]; then
  135.                         echo
  136.                         echo "Already in the top directory"
  137.                         echo
  138.                         doc=
  139.                     else
  140.                         cd $doc
  141.                         echo
  142.                         echo "Available documents:"
  143.                         echo
  144.                         ls -C
  145.                         echo
  146.                     fi
  147.                     ;;
  148.                 *)
  149.                     cd $doc
  150.                     echo
  151.                     echo "Document directory $doc contains the following:"
  152.                     echo
  153.                     ls -C
  154.                     echo
  155.                     ;;
  156.             esac
  157.         elif [ -f "$doc" ]; then
  158.             echo
  159.             ${PAGER:-less} $doc
  160.             echo
  161.         elif [ "$doc" != "quit" ]; then
  162.             echo
  163.             echo "No such document or directory: $doc"
  164.             echo
  165.         fi
  166.     done
  167.  
  168.     cd $HERE
  169. }
  170.  
  171.  
  172. function location()
  173. {
  174.     # If we have been given a path list we'll use it.
  175.     if [ "$2" = "" ]; then
  176.         path=$PKGPATH
  177.     else
  178.         path=$2
  179.     fi
  180.  
  181.     echo $path | tr ':' '\n' | while read p
  182.     do
  183.         if [ -n "$p" -a "$p" != "." ]; then
  184.             it=`ls -1dr $p/$1 $p/$1-* 2> /dev/null | head -1`
  185.         else
  186.             it=`ls -1dr $1 $1-* 2> /dev/null | head -1`
  187.         fi
  188.         if [ -n "$it" ]; then
  189.             echo $it
  190.             exit
  191.         fi
  192. #        if [ -e $p/$1 ]; then
  193. #            if [ "$p" != "." ]; then
  194. #                echo $p/$1
  195. #            else
  196. #                echo $1
  197. #            fi
  198. #            exit
  199. #        fi
  200.     done
  201. }
  202.  
  203.  
  204. function gen_list()
  205. {
  206.     if [ ! -r $1/PKG/map -a -z "$quiet" ]; then
  207.         echo $use_escapes "(no map) \c" 1>&2
  208.         return
  209.     fi
  210.  
  211.     awk '
  212. BEGIN        { def_ver = "0" }
  213. /^#/        { done=1 }
  214. /^[ \t]*$/    { done=1 }
  215. $1 == "VERSION"    {
  216.             def_ver = $2
  217.             done = 1
  218.         }
  219. done == 0    {
  220.             if ($2 ~ /[*?]/) {
  221.                 op = $1
  222.                 dest = $3
  223.                 if (NF == 4)
  224.                     ver = $4
  225.                 else
  226.                     ver = def_ver
  227.                 cmd = sprintf("ls -1 %s/%s 2> /dev/null; exit 0", basedir, $2)
  228.                 while (cmd | getline) {
  229.                     printf "%s %s %s/%s %s\n", op, $0, dest, substr($0, 1+match($0, "/[^/]*$")), ver
  230.                 }
  231.             } else {
  232.                 if (NF == 4)
  233.                     ver = $4
  234.                 else
  235.                     ver = def_ver
  236.                 printf "%s %s/%s %s %s\n", $1, basedir, $2, $3, ver
  237.             }
  238.         }
  239.         { done=0 }
  240.     ' basedir=$1 $1/PKG/map
  241. }
  242.  
  243.  
  244. function do_install()
  245. {
  246.     target=$1
  247.  
  248.     $ZCAT $target/.map | awk '
  249. BEGIN        {
  250.             last_path = ""
  251.         }
  252. $3 != last_path    {
  253.             if (match($3, "^/.*") == 1)
  254.                 printf "%s %s %s\n", $1, $2, $3
  255.             else
  256.                 printf "%s %s %s/%s\n", $1, $2, target, $3
  257.             last_path = $3
  258.         }
  259.     ' target=$target | /usr/lib/pkg/pipe-inst $no_action
  260. }
  261.  
  262.  
  263. function do_purge()
  264. {
  265.     dir=$1
  266.  
  267.     $ZCAT $dir/.map | awk '
  268. BEGIN        {
  269.             last_path = ""
  270.         }
  271. $3 == last_path    {
  272.             print $2
  273.             last_path = $3
  274.         }
  275.     ' target=$dir | /usr/lib/pkg/pipe-rm $no_action
  276. }
  277.  
  278.  
  279. function mount_disk()
  280. {
  281.     for i in $FSTYPES
  282.     do
  283.         mount -t $i $1 $2 2> /dev/null
  284.         if [ $? -eq 0 ]; then
  285.             ok=yes
  286.             break
  287.         fi
  288.     done
  289.     if [ -z "$ok" ]; then
  290.         echo "error: unable to mount disk." 1>&2
  291.         return 1
  292.     else
  293.         return 0
  294.     fi
  295. }
  296.  
  297.  
  298. function add_package()
  299. {
  300.     if [ -f $target/.installed ]; then
  301.         curr_pkg=`egrep "/$1(-[-0123456789.]*)?$" $target/.installed`
  302.     else
  303.         curr_pkg=
  304.     fi
  305.     if [ -n "$curr_pkg" ]; then
  306.         if [ -z "$quiet" ]; then
  307.             echo $1 is already installed here from $curr_pkg.
  308.         fi
  309.     else
  310.         locn=`location $1`
  311.         [ -n "$locn" ] && case "$locn" in
  312.             /*)
  313.                 echo $locn >> $target/.installed \
  314.                 && [ -z "$quiet" ] && echo "Added $1 to $target."
  315.                 ;;
  316.  
  317.             *)
  318.                 echo `pwd`/$locn >> $target/.installed \
  319.                 && [ -z "$quiet" ] && echo "Added $1 to $target"
  320.                 ;;
  321.         esac
  322.     fi
  323. }
  324.  
  325.  
  326. function remove_package()
  327. {
  328.     if [ -z "$quiet" ]; then
  329.         echo "Remove from $target:"
  330.         egrep "$1" $target/.installed
  331.     fi
  332.     mv $target/.installed $target/.installed.old
  333.     egrep -v "/$1(-[-0123456789.]*)?$" $target/.installed.old > $target/.installed
  334.     rm -f $target/.installed.old
  335. }
  336.  
  337.  
  338. function install_package()
  339. {
  340.     # Note what we have already.
  341.     ls -1 > /tmp/pkgA$$
  342.  
  343.     # If we are given a block device we try and mount it, extract any
  344.     # packages we find on it and then unmount it again. Otherwise we
  345.     # assume we were just given a package name.
  346.     if [ -b "$1" ]; then
  347.         rm -f /tmp/pkgm$$
  348.         mkdir /tmp/pkgm$$
  349.         if mount_disk $1 /tmp/pkgm$$; then
  350.             for i in /tmp/pkgm$$/*
  351.             do
  352.                 [ -z "$quiet" ] && echo "Extracting "`basename $i`
  353.                 tar xfzpsS "$i"
  354.             done
  355.  
  356.             umount /tmp/pkgm$$
  357.             rmdir /tmp/pkgm$$
  358.         else
  359.             rm /tmp/pkgA$$
  360.             rmdir /tmp/pkgm$$
  361.             exit 1
  362.         fi
  363.     else
  364.         [ -z "$quiet" ] && echo "Extracting $1"
  365.         tar xfzpsS "$1"
  366.     fi
  367.  
  368.     # Find what we have now.
  369.     ls -1 > /tmp/pkgB$$
  370.  
  371.     # Add anything that was not here originally.
  372.     comm -13 /tmp/pkgA$$ /tmp/pkgB$$ | while read i
  373.     do
  374.         add_package "$i"
  375.     done
  376.     rm -f /tmp/pkgA$$ /tmp/pkgB$$
  377. }
  378.  
  379.  
  380. # If we haven't any arguments just display the usage message.
  381. if [ $# -eq 0 ]; then
  382.     usage
  383.     exit 1
  384. fi
  385.  
  386. no_action=
  387. quiet=
  388. while [ $# -ne 0 ]
  389. do
  390.     case "$1" in
  391.         -n)
  392.             no_action=-n
  393.             shift
  394.             ;;
  395.  
  396.         -q|--quiet|--quite)
  397.             # Yeah, quite is a mispelling but we can guess
  398.             # what they mean.
  399.             quiet=yes
  400.             shift
  401.             ;;
  402.  
  403.         -t|--target)
  404.             if [ -z "$2" ]; then
  405.                 echo "$1 requires an argument"
  406.                 exit 1
  407.             fi
  408.             target=$2
  409.             if [ "$target" = "/" ]; then
  410.                 target=
  411.             fi
  412.             shift; shift
  413.             ;;
  414.  
  415.         --install|--extract)
  416.             if [ -z "$2" ]; then
  417.                 echo "$1 requires an argument" 1>&2
  418.                 exit 1
  419.             fi
  420.             shift
  421.  
  422.             done=
  423.             while [ -n "$1" -a -z "$done" ]
  424.             do
  425.                 case "$1" in
  426.                     -*)    done=yes
  427.                         ;;
  428.                     *)
  429.                         install_package "$1"
  430.                         shift
  431.                         ;;
  432.                 esac
  433.             done
  434.             ;;
  435.         -a|--add)
  436.             if [ -z "$2" ]; then
  437.                 echo "$1 requires an argument" 1>&2
  438.                 exit 1
  439.             fi
  440.             shift
  441.             done=
  442.             while [ -n "$1" -a -z "$done" ]
  443.             do
  444.                 case "$1" in
  445.                     -*)    done=yes
  446.                         ;;
  447.                     *)    add_package "$1"
  448.                         shift
  449.                         ;;
  450.                 esac
  451.             done
  452.             ;;
  453.  
  454.         --purge)
  455.             echo
  456.             echo "This operation removes files from the actual package directories which"
  457.             echo "have been superceeded by later versions and are no longer required on"
  458.             echo "your system."
  459.             echo
  460.             ans=
  461.             while [ "$ans" != "y" -a "$ans" != "Y" -a "$ans" != "n" -a "$ans" != "N" ]
  462.             do
  463.                 echo $use_escapes "Are you sure you want to do this? (y/n): \c"
  464.                 read ans
  465.             done
  466.             if [ "$ans" = "y" -o "$ans" = "Y" ]; then
  467.                 do_purge $target
  468.             fi
  469.             shift
  470.             ;;
  471.         --conf*)
  472.             if [ -z "$2" ]; then
  473.                 echo "$1 requires an argument" 1>&2
  474.                 exit 1
  475.             fi
  476.             if [ -f $target/.installed ]; then
  477.                 locn=`grep "$2" $target/.installed`
  478.             else
  479.                 locn=
  480.             fi
  481.             if [ -z "$locn" ]; then
  482.                 locn=`location $2`
  483.                 [ -n "$locn" ] && case "$locn" in
  484.                     /*)
  485.                         ;;
  486.                     *)
  487.                         locn=`pwd`/$locn
  488.                         ;;
  489.                 esac
  490.             fi
  491.             if [ -n "$locn" ]; then
  492.                 if [ -x $locn/PKG/configure ]; then
  493.                     (cd $locn ; PKG/configure)
  494.                 else
  495.                     echo "No configuration is necessary for $2"
  496.                 fi
  497.             else
  498.                 echo "can't find package $2"
  499.             fi
  500.             shift; shift
  501.             ;;
  502.  
  503.         --doc*|--read*)
  504.             if [ -z "$2" ]; then
  505.                 echo "$1 requires an argument" 1>&2
  506.                 exit 1
  507.             fi
  508.             if [ -f $target/.installed ]; then
  509.                 locn=`grep "$2" $target/.installed`
  510.             else
  511.                 locn=
  512.             fi
  513.             if [ -z "$locn" ]; then
  514.                 locn=`location $2`
  515.                 [ -n "$locn" ] && case "$locn" in
  516.                     /*)
  517.                         ;;
  518.                     *)
  519.                         locn=`pwd`/$locn
  520.                         ;;
  521.                 esac
  522.             fi
  523.             if [ -n "$locn" ]; then
  524.                 read_docs $locn
  525.             else
  526.                 echo "can't find package $2"
  527.             fi
  528.             shift; shift
  529.             ;;
  530.         -d|--del*|--rm|--rem*)
  531.             if [ -z "$2" ]; then
  532.                 echo "$2 requires an argument" 1>&2
  533.                 exit 1
  534.             fi
  535.             shift
  536.             done=
  537.             while [ -n "$1" -a -z "$done" ]
  538.             do
  539.                 case "$1" in
  540.                     -*)    done=yes
  541.                         ;;
  542.                     *)    remove_package "$1"
  543.                         shift
  544.                         ;;
  545.                 esac
  546.             done
  547.             ;;
  548.  
  549.         -l|--list|--ls)
  550.             if [ ! -s $target/.installed ]; then
  551.                 if [ -z "$target" ]; then
  552.                     echo "Nothing installed in /."
  553.                 else
  554.                     echo "Nothing installed in $target."
  555.                 fi
  556.             else
  557.                 if [ -z "$target" ]; then
  558.                     echo "Packages installed in /:"
  559.                 else
  560.                     echo "Packages installed in $target:"
  561.                 fi
  562.                 awk -F/ '{
  563.                     printf "\t%-20s\t(%s)\n", $NF, $0
  564.                 }' $target/.installed
  565.             fi
  566.             shift
  567.             ;;
  568.  
  569.         -i|--info|--what*|--where*)
  570.             if [ -z "$2" ]; then
  571.                 echo "--info requires an argument" 1>&2
  572.                 exit 1
  573.             fi
  574.             $ZCAT $target/.map | egrep $2 | awk '
  575. BEGIN        {
  576.             done=0
  577.             last_path=""
  578.         }
  579. $3 != last_path    {
  580.             print $3
  581.             if ($4 != "0")
  582.                 print "\tVersion", $4
  583.             last_path = $3
  584.             done=0
  585.         }
  586.  
  587. done == 0 && $1 == "COPY"    { print "\tcopy of", $2 }
  588. done == 0 && $1 == "COPYNEW"    { print "\tbased on", $2 }
  589. done == 0 && $1 == "LINK"    { print "\tlink to", $2 }
  590. done == 0 && $1 == "SLINK"    { print "\tsymlink to", $2 }
  591.  
  592. done == 0    { done=1 }
  593.             '
  594.             shift; shift
  595.             ;;
  596.  
  597.         -r|--rebuild)
  598.             if [ ! -f $target/.installed ]; then
  599.                 echo "No packages installed in $target."
  600.                 echo "Use --add to add a package."
  601.                 exit 1
  602.             fi
  603.             [ -z "$quiet" ] && echo $use_escapes "Merging package maps:\n\t\c"
  604.             rm -f $target/.map.old
  605.             [ -f $target/.map ] && mv $target/.map $target/.map.old
  606.             while read i
  607.             do
  608.                 [ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
  609.                 gen_list $i
  610.             done < $target/.installed | sort -b -r +2 | $COMP > $target/.map
  611.             [ -z "$quiet" ] && echo
  612.  
  613.             [ -z "$quiet" ] && echo
  614.             if [ -f $target/.map.old ]; then
  615.                 [ -z "$quiet" ] && echo "Removing obsolete files:"
  616.                 $ZCAT $target/.map | awk '!/^COPYNEW/ { print $3 }' | sort | uniq > /tmp/pkg$$
  617.                 $ZCAT $target/.map.old | awk '!/^COPYNEW/ { print $3 }' | sort | uniq | comm -13 /tmp/pkg$$ - | /usr/lib/pkg/pipe-rm $no_action $target
  618.                 rm -f /tmp/pkg$$
  619.             fi
  620.  
  621.             [ -z "$quiet" ] && echo $use_escapes "\nRunning pre-install scripts:\n\t\c"
  622.             while read i
  623.             do
  624.                 [ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
  625.                 if [ -r $i/PKG/pre-install ]; then
  626.                     (cd $i; sh ./PKG/pre-install $no_action $target < /dev/tty > /dev/tty 2>&1)
  627.                 fi
  628.             done < $target/.installed
  629.             [ -z "$quiet" ] && echo
  630.  
  631.             [ -z "$quiet" ] && echo $use_escapes "\nBuilding target structure..."
  632.             do_install $target
  633.  
  634.             [ -z "$quiet" ] && echo $use_escapes "\nRunning post-install scripts:\n\t\c"
  635.             while read i
  636.             do
  637.                 [ -z "$quiet" ] && echo $use_escapes "`basename $i` \c" 1>&2
  638.                 if [ -r $i/PKG/post-install ]; then
  639.                     (cd $i; sh ./PKG/post-install $no_action $target < /dev/tty > /dev/tty 2>&1)
  640.                 fi
  641.             done < $target/.installed
  642.             [ -z "$quiet" ] && echo
  643.  
  644.             if [ -n "$no_action" -a -f $target/.map.old ]; then
  645.                 rm -f $target/.map
  646.                 mv $target/.map.old $target/.map
  647.             else
  648.                 rm -f $target/.map.old
  649.             fi
  650.  
  651.             if [ -z "$no_action" -a -x /usr/lib/pkg/prepare ]; then
  652.                 /usr/lib/pkg/prepare $target
  653.             fi
  654.             shift
  655.             ;;
  656.  
  657.         *)
  658.             echo "${progname}: unrecognised option \`$1'"
  659.             echo "run ${progname} with no arguments for help"
  660.             exit 1
  661.             ;;
  662.     esac
  663. done
  664.  
  665. # If the .installed file is newer than the .map file (if any) then we will
  666. # need to rebuild the structure at some stage.
  667. if [ -z "$quiet" -a -f $target/.installed ]; then
  668.     if [ ! -f $target/.map -o $target/.installed -nt $target/.map ]; then
  669.         echo "The target structure may not represent currently installed packages."
  670.         echo "Use --rebuild to rebuild the target structure."
  671.     fi
  672. fi
  673.